import 'dart:ui';

import 'package:flutter/material.dart';

class TimeoutBtn extends StatefulWidget {
  const TimeoutBtn({super.key});

  @override
  State<TimeoutBtn> createState() => _TimeoutBtnState();
}

class _TimeoutBtnState extends State<TimeoutBtn>
    with SingleTickerProviderStateMixin {
  bool _isFirst = true;
  int _timeCount = 5;
  late final AnimationController _ctrl =
      AnimationController(vsync: this, duration: Duration(seconds: _timeCount));

  @override
  void initState() {
    // TODO: implement initState
    // _ctrl.repeat();
    super.initState();
  }

  @override
  void dispose() {
    // TODO: implement dispose
    _ctrl.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('倒计时按钮'),
        ),
        body: Container(
          constraints: BoxConstraints.expand(),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Material(
                // 设置背景颜色 默认矩形
                color: Colors.white,
                child: InkWell(
                    //点击事件回调
                    onTap: () {
                      if (_isFirst) {
                        _isFirst = false;
                      }
                      _ctrl.reset();
                      _ctrl.forward();
                    },
                    //不要在这里设置背景色，for则会遮挡水波纹效果,如果设置的话尽量设置Material下面的color来实现背景色
                    child: Stack(
                      alignment: Alignment.center,
                      children: [
                        Container(
                          width: 300,
                          height: 300,
                          child: CustomPaint(
                            painter:
                                TimeoutBtnPaint(controller: _ctrl, radius: 20),
                          ),
                        ),
                        AnimatedBuilder(
                            animation: _ctrl,
                            builder: (ctx, child) => Text(
                                '${_isFirst ? '发送验证码' : _ctrl.value == 1 ? '重新发送' : "已发送 ${(_timeCount - _timeCount * _ctrl.value).toInt()}"}'))
                      ],
                    )),
              ),
            ],
          ),
        ));
  }
}

class TimeoutBtnPaint extends CustomPainter {
  final AnimationController controller;
  final double radius;
  final double borderWidth;
  final Color color;
  final Color borderColor;

  TimeoutBtnPaint(
      {required this.controller,
      this.color = Colors.blue,
      this.radius = 0,
      this.borderColor = Colors.grey,
      this.borderWidth = 2})
      : super(repaint: controller);
  late final Paint _paint = Paint()
    ..color = color
    ..strokeWidth = borderWidth
    ..style = PaintingStyle.stroke;

  double get _radius => radius ?? 0;

  Radius get _circularRadius => Radius.circular(_radius);
   double _width = 0;
   double _height =0;
  double get width =>_width;
  double get height =>_height;
  late final RRect rRect = RRect.fromRectAndRadius(
      Rect.fromLTWH(0, 0,_width,height), Radius.circular(_radius));
  // 画出一个带圆角的矩形
  late final Path _path = Path()
    ..moveTo(width / 2, 0)
    ..relativeLineTo(width / 2 - _radius, 0)
    ..relativeArcToPoint(Offset(_radius, _radius), radius: _circularRadius)
    ..relativeLineTo(0, height - _radius * 2)
    ..relativeArcToPoint(Offset(-_radius, _radius), radius: _circularRadius)
    ..relativeLineTo(-width + _radius * 2, 0)
    ..relativeArcToPoint(Offset(-_radius, -_radius), radius: _circularRadius)
    ..relativeLineTo(0, -height + _radius * 2)
    ..relativeArcToPoint(Offset(_radius, -_radius), radius: _circularRadius)
    ..relativeLineTo(width / 2 - _radius, 0)
    ..close();
  @override
  void paint(Canvas canvas, Size size) {
     _width = size.width;
    _height = size.height;
    // 初始化铺满颜色的正方形
    // 画笔画出矩形
    canvas.drawPath(
        _path,
        _paint
          ..style = PaintingStyle.stroke
          ..color = color);
    if (controller.value == 0) {
      // canvas.drawRRect(
      //     rRect,
      //     _paint
      //       ..color = color
      //       ..style = PaintingStyle.fill);
      return;
    }
    // 计算 path 长度的数组
    final PathMetrics metrics = _path.computeMetrics();
    for (final PathMetric metric in metrics) {
      _drawMatric(canvas, _paint, metric);
    }
  }

  @override
  bool shouldRepaint(covariant TimeoutBtnPaint oldDelegate) {
    // TODO: implement shouldRepaint
    return radius != oldDelegate.radius;
  }

  void _drawMatric(Canvas canvas, Paint paint, PathMetric metric) {
    // 一截 一截画出覆盖的颜色
    // 使用 path 长度的数组 * controller的value 计算 用0-1的动画区间画出所占path路径长度的百分比，这样就可以实现从0到100%的效果
    canvas.drawPath(metric.extractPath(0, metric.length * controller.value),
        paint..color = borderColor);
  }
}
